<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:x="https://www.texmacs.org/2002/extensions" xmlns:m="http://www.w3.org/1998/Math/MathML">
  <head>
    <title>TeXmacs notes</title>
    <meta content="TeXmacs 1.99.15" name="generator"></meta>
    <link href="../resources/notes-base.css" type="text/css" rel="stylesheet"></link>
    <link href="../resources/blog-icon.png" rel="icon"></link>
    <script src="../resources/highlight.pack.js" language="javascript" defer></script>
    <script src="../resources/notes-base.js" language="javascript" defer></script>
  </head>
  <body>
    <div class="toggle" style="display: none">
      <p>
        
      </p>
    </div>
    <div class="notes-header">
      <p>
        <img class="image" src="../resources/texmacs-blog-transparent.png" width="28.116784"></img><span style="margin-left: 2pt"></span><a href="./main.html">[main]</a><em
        class="notes-header-name">Notes on TeXmacs</em>
      </p>
    </div>
    <h1 id="auto-1">Implementing previews for link targets<span style="margin-left: 1em"></span></h1>
    <p>
      [last revision: 2020.11.9]
    </p>
    <p>
      Let us see how Joris implemented a preview for link target in <a href="https://svn.savannah.gnu.org/viewvc/texmacs?view=revision&amp;revision=13081">r13081</a>.
      This requires adding new functionalities at several levels.
    </p>
    <p>
      Preview have to be shown in a popup balloon as soon as the user hovers
      the associate reference locus with the mouse. So we need to modify the
      <font class="tmweb-markup">reference</font> and <font class="tmweb-markup">pageref</font> tags.
      There are &ldquo;primitive&rdquo; tags defined in the <class style="font-variant: small-caps">C++</class>
      source <code>src/Typeset/Env/env_default.cpp</code> with
    </p>
    <div class="tmweb-code">
      <pre class="verbatim cpp" xml:space="preserve">
tree ln3 (LINK, &quot;hyperlink&quot;, copy (ref_id), copy (dest_ref));
env (&quot;reference&quot;) = tree (MACRO, &quot;Id&quot;, 
                                 tree (LOCUS, copy (ref_id), 
                                              ln3, reftxt));
env (&quot;pageref&quot;) = tree (MACRO, &quot;Id&quot;, 
                               tree (LOCUS, copy (ref_id), 
                                            copy (ln3), preftxt));</pre>
    </div>
    <p>
      A new package at <code>packages/utilities/preview-ref.ts</code>
      containing a redefinition of the <font class="tmweb-markup">reference</font> and <font
      class="tmweb-markup">pageref</font> tags:
    </p>
    <div class="tmweb-code">
      <p>
        <font color="blue">&lt;</font>document<font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>use-module<font color="blue">|</font><font color="#228"><tt>(link
        ref-edit)</tt></font><font color="blue">&gt;</font></font><font color="blue">|</font><font
        color="black"></font><font color="blue">|</font><font color="black"><font color="blue">&lt;</font>assign<font
        color="blue">|</font><font color="#008000"><i>reference</i></font><font color="blue">|</font><font
        color="black"><font color="blue">&lt;</font>macro<font color="blue">|</font><font color="brown"><i>Id</i></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>locus<font color="blue">|</font><font
        color="black"><font color="blue">&lt;</font>id<font color="blue">|</font><font color="#228"><tt><font
        color="blue">&lt;</font>hard-id<font color="blue">|</font><font color="black"><font
        color="brown"><i>Id</i></font></font><font color="blue">&gt;</font></tt></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>link<font color="blue">|</font><font color="black">hyperlink</font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>id<font color="blue">|</font><font
        color="#228"><tt><font color="blue">&lt;</font>hard-id<font color="blue">|</font><font
        color="black"><font color="brown"><i>Id</i></font></font><font color="blue">&gt;</font></tt></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>url<font color="blue">|</font><font color="#228"><tt><font
        color="blue">&lt;</font>merge<font color="blue">|</font><font color="black">#</font><font
        color="blue">|</font><font color="black"><font color="brown"><i>Id</i></font></font><font
        color="blue">&gt;</font></tt></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>link<font color="blue">|</font><font color="black">mouse-over</font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>id<font color="blue">|</font><font
        color="#228"><tt><font color="blue">&lt;</font>hard-id<font color="blue">|</font><font
        color="black"><font color="brown"><i>Id</i></font></font><font color="blue">&gt;</font></tt></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>script<font color="blue">|</font><font color="#228"><tt>preview-reference</tt></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>quote-arg<font
        color="blue">|</font><font color="brown"><i>Id</i></font><font color="blue">&gt;</font></font><font
        color="blue">|</font><font color="black"><font color="brown"><i>Id</i></font></font><font
        color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font color="blue">|</font><font
        color="black"><font color="blue">&lt;</font>get-binding<font color="blue">|</font><font
        color="#228"><tt><font color="brown"><i>Id</i></font></tt></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font
        color="blue">|</font><font color="black"></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>assign<font color="blue">|</font><font color="#008000"><i>pageref</i></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>macro<font color="blue">|</font><font
        color="brown"><i>Id</i></font><font color="blue">|</font><font color="black"><font color="blue">&lt;</font>locus<font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>id<font color="blue">|</font><font
        color="#228"><tt><font color="blue">&lt;</font>hard-id<font color="blue">|</font><font
        color="black"><font color="brown"><i>Id</i></font></font><font color="blue">&gt;</font></tt></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>link<font color="blue">|</font><font color="black">hyperlink</font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>id<font color="blue">|</font><font
        color="#228"><tt><font color="blue">&lt;</font>hard-id<font color="blue">|</font><font
        color="black"><font color="brown"><i>Id</i></font></font><font color="blue">&gt;</font></tt></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>url<font color="blue">|</font><font color="#228"><tt><font
        color="blue">&lt;</font>merge<font color="blue">|</font><font color="black">#</font><font
        color="blue">|</font><font color="black"><font color="brown"><i>Id</i></font></font><font
        color="blue">&gt;</font></tt></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>link<font color="blue">|</font><font color="black">mouse-over</font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>id<font color="blue">|</font><font
        color="#228"><tt><font color="blue">&lt;</font>hard-id<font color="blue">|</font><font
        color="black"><font color="brown"><i>Id</i></font></font><font color="blue">&gt;</font></tt></font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>script<font color="blue">|</font><font color="#228"><tt>preview-reference</tt></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>quote-arg<font
        color="blue">|</font><font color="brown"><i>Id</i></font><font color="blue">&gt;</font></font><font
        color="blue">|</font><font color="black"><font color="brown"><i>Id</i></font></font><font
        color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font color="blue">|</font><font
        color="black"><font color="blue">&lt;</font>get-binding<font color="blue">|</font><font
        color="#228"><tt><font color="brown"><i>Id</i></font></tt></font><font color="blue">|</font><font
        color="#848">1</font><font color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font color="blue">&gt;</font>
      </p>
    </div>
    <p>
      Note the use of the <font class="tmweb-markup">use-module</font> tag to indicate that
      the <class style="font-variant: small-caps">Scheme</class> module <tt class="verbatim scheme">(link ref-edit)</tt>
      must be made available to TeXmacs beforehand in order to be able to call
      the <class style="font-variant: small-caps">Scheme</class> procedure <tt class="verbatim scheme">preview-reference</tt>.
      The module <tt class="verbatim scheme">(link ref-edit)</tt>, defined in the <class style="font-variant: small-caps">Scheme</class>
      source <code>/progs/link/ref-edit.scm</code>, being with
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(texmacs-module (link ref-edit)
  (:use (generic generic-edit)
        (generic document-part)
        (text text-drd)))</pre>
    </div>
    <p>
      and contains the definition of <tt class="verbatim scheme">preview-reference</tt> as a
      <tt class="verbatim scheme">tm-define</tt> (i.e. a global symbol visible in all the
      program). Note the <tt class="verbatim scheme">(:secure #t)</tt> which indicates to
      TeXmacs that this producedure does not perform any <i>dangerous</i>
      operation and therefore can be called without notifying the user.
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(tm-define (preview-reference body body*)
  (:secure #t)
  (and-with ref (tree-up body)
    (with (x1 y1 x2 y2) (tree-bounding-rectangle ref)
      (and-let* ((packs (get-style-list))
                 (pre (document-get-preamble (buffer-tree)))
                 (id (and (tree-atomic? body*) 
                          (tree-&gt;string body*)))
                 (balloon (ref-preview id))
                 (zf (get-window-zoom-factor))
                 (sf (/ 4.0 zf))
                 (mag (number-&gt;string (/ zf 1.5)))
                 (balloon* &lsquo;(with &quot;magnification&quot; ,mag ,balloon))
                 (w (widget-texmacs-output
                     &lsquo;(surround (hide-preamble ,pre) &quot;&quot; ,balloon*)
                     &lsquo;(style (tuple ,@packs)))))
        (show-balloon w x1 (- y1 1280))))))</pre>
    </div>
    <p>
      This procedure invoke <tt class="verbatim scheme">show-balloon</tt> to display a popup to
      the user which contains a widget to output TeXmacs documents (built via
      <tt class="verbatim scheme">widget-texmacs-output</tt>) after suitably scaling it via a
      <font class="tmweb-markup">magnification</font> tag. The content itself is produced by
      the procedure <tt class="verbatim scheme">ref-preview</tt> :
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(tm-define (ref-preview id)
  (and-with l (and-nnull? (search-label (buffer-tree) id))
    (label-preview (car l))))</pre>
    </div>
    <p>
      which in turn calls the helper procedure <tt class="verbatim scheme">label-preview</tt>
      (internal to the module):
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(define (label-preview t)
  (and-with doc (tree-search-upwards t preview-context?)
    (with math? (tree-search-upwards t math-context?)
      (when (and (tree-up doc) (tree-up (tree-up doc))
                 (tree-is? (tree-up doc) 'document)
                 (preview-expand-context? (tree-up (tree-up doc))))
        (set! doc (tree-up doc)))
      (when (tm-is? doc 'row)
        (set! doc (apply tmconcat (map uncell (tm-children doc)))))
      (set! doc (clean-preview doc))
      (when math?
        (set! doc &lsquo;(with &lsquo;&lsquo;math-display'' &lsquo;&lsquo;true'' (math ,doc))))
      &lsquo;(preview-balloon ,doc))))</pre>
    </div>
    <p>
      The construction of the preview content is performed by the snippet <tt
      class="verbatim scheme">&lsquo;(preview-balloon ,doc)</tt> which evaluates to a TeXmacs
      s-tree containing a singe <font class="tmweb-markup">preview-balloon</font> tag for
      the rendering of the preview. This is defined at the macro language
      level in <code>packages/standard/std-fold.ts</code> as
    </p>
    <div class="tmweb-code">
      <p>
        <font color="blue">&lt;</font>assign<font color="blue">|</font><font color="#008000"><i>preview-balloon</i></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>macro<font color="blue">|</font><font
        color="brown"><i>body</i></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>tabular<font color="blue">|</font><font color="#C68"><font
        color="blue">&lt;</font>tformat<font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>cwith<font color="blue">|</font><font color="#848">1</font><font
        color="blue">|</font><font color="#848">1</font><font color="blue">|</font><font color="#848">1</font><font
        color="blue">|</font><font color="#848">1</font><font color="blue">|</font><font color="#008000"><i>cell-hyphen</i></font><font
        color="blue">|</font><font color="black">t</font><font color="blue">&gt;</font></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>cwith<font color="blue">|</font><font
        color="#848">1</font><font color="blue">|</font><font color="#848">1</font><font color="blue">|</font><font
        color="#848">1</font><font color="blue">|</font><font color="#848">1</font><font color="blue">|</font><font
        color="#008000"><i>cell-background</i></font><font color="blue">|</font><font color="black">#edc</font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>twith<font color="blue">|</font><font color="#008000"><i>table-width</i></font><font
        color="blue">|</font><font color="black">40em</font><font color="blue">&gt;</font></font><font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>twith<font color="blue">|</font><font
        color="#008000"><i>table-hmode</i></font><font color="blue">|</font><font color="black">min</font><font
        color="blue">&gt;</font></font><font color="blue">|</font><font color="black"><font
        color="blue">&lt;</font>table<font color="blue">|</font><font color="black"><font color="blue">&lt;</font>row<font
        color="blue">|</font><font color="black"><font color="blue">&lt;</font>cell<font color="blue">|</font><font
        color="black"><font color="blue">&lt;</font>document<font color="blue">|</font><font
        color="black"><font color="brown"><i>body</i></font></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font color="blue">&gt;</font></font><font
        color="blue">&gt;</font>
      </p>
    </div>
    <p>
      This markup provides a custom style  and background color for the
      preview area, including a minimum width. 
    </p>
    <p>
      The <font color="brown"><i>body</i></font> argument is feed with a meaningful
      snippet of the source of the link. This is determined by the <tt class="verbatim scheme">label-preview</tt>
      procedure by navigating the document tree from the source position (as
      indicated by the <tt class="verbatim scheme">t</tt> parameter) towards higher levels of
      the structure hierarchy via <tt class="verbatim scheme">(tree-search-upwards t
      preview-context?)</tt>. The predicate <tt class="verbatim scheme">preview-context?</tt>
      looks for meaningful context: a row of a table or a leaf of a <font
      class="tmweb-markup">document</font> tag:
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(define (preview-context? t)
  (or (tree-is? t 'row)
      (and (tree-up t) (tree-is? (tree-up t) 'document))))</pre>
    </div>
    <p>
      We want also to include some major markup in the preview, e.g. theorems,
      etc<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span
      style="margin-left: 0.16665em"></span>
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(define (preview-expand-context? t)
  (tree-in? t '(theorem proposition lemma corollary conjecture
                theorem* proposition* lemma* corollary* conjecture*
                definition axiom
                definition* axiom*)))</pre>
    </div>
    <p>
      The procedure <tt class="verbatim scheme">clean-preview</tt> preforms some recursive
      cleaning on the source snippet:
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(define (clean-preview t)
  (cond ((tm-is? t 'document)
         &lsquo;(document ,@(map clean-preview (tm-children t))))
        ((tm-is? t 'concat)
         (apply tmconcat (map clean-preview (tm-children t))))
        ((tm-in? t (section-tag-list))
         (with l (symbol-append (tm-label t) '*)
           &lsquo;(,l ,@(tm-children t))))
        ((tm-in? t '(label item item* 
                           bibitem bibitem* eq-number)) &quot;&quot;)
        ((or (tm-func? t 'equation 1) (tm-func? t 'equation* 1))
         &lsquo;(equation* ,(clean-preview (tm-ref t 0))))
        ((tm-in? t '(eqnarray eqnarray* tformat table row cell))
         &lsquo;(,(tm-label t) ,@(map clean-preview (tm-children t))))
        (else t)))</pre>
    </div>
    <p>
      
    </p>
  </body>
</html>